package model;

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.apache.log4j.Logger;

@Entity
public class NotaFiscal {
	private static Logger logger = Logger.getLogger(NotaFiscal.class);

	/* Atributos normais */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long notafiscal_id;

	private String numerodanotafiscal;

	private String cnpj_cpf;

	/* Atributos de relacionamento */
	@ManyToOne(cascade = { CascadeType.PERSIST })
	@JoinColumn(name = "entrega_id")
	private Entrega entrega;

	@ManyToOne(cascade = { CascadeType.MERGE})
	@JoinColumn(name = "endereco_id")
	private Endereco endereco;

	@ManyToMany(mappedBy = "notasfiscais")
	private Collection<Cliente> clientes = new ArrayList<Cliente>();

	@ManyToMany(mappedBy = "notasfiscais")
	private Collection<Produto> produtos = new ArrayList<Produto>();

	@OneToMany(mappedBy = "notaFiscal")
	private Collection<Item> items = new ArrayList<Item>();

	/* Construtor sem argumentos para o JPA */
	public NotaFiscal() {
		/* Uma gambiarra oficial para descobrir quem chamou o construtor */
		try {
			throw new IllegalStateException();
		} catch (IllegalStateException e) {
			StackTraceElement[] stackTrace = e.getStackTrace();
			StackTraceElement stackTraceElement = stackTrace[1];
			if(stackTraceElement.getClassName().equals("sun.reflect.NativeConstructorAccessorImpl")){
				NotaFiscal.logger.debug("JPA construindo uma notafiscal");
			}else{
				NotaFiscal.logger.info("Construindo uma notafiscal");
			}
		}
	}

	/* RELACIONAMENTO COM ENTREGA */
	public Entrega getEntrega() {
		return entrega;
	}

	public void setEntrega(Entrega entrega) {
		this.entrega = entrega;
	}

	/* RELACIONAMENTO COM ENDERECO */
	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	/* RELACIONAMENTO COM PRODUTO */
	public Collection<Produto> getProdutos() {
		return produtos;
	}

	public void addProduto(Produto produto) {
		this.produtos.add(produto);
	}

	/* RELACIONAMENTO COM CLIENTE */
	public Collection<Cliente> getClientes() {
		return clientes;
	}

	public void addCliente(Cliente cliente) {
		this.clientes.add(cliente);
	}

	/* RELACIONAMENTO COM ITEM */
	public Collection<Item> getItems() {
		return items;
	}

	public void addItem(Item item) {
		this.items.add(item);
	}

	/* GETTERS E SETTERS */
	public String getCnpj_cpf() {
		return cnpj_cpf;
	}

	public void setCnpj_cpf(String cnpj_cpf) {
		this.cnpj_cpf = cnpj_cpf;
	}

	public Long getNotafiscal_id() {
		return notafiscal_id;
	}

	public void setNotafiscal_id(Long notafiscal_id) {
		this.notafiscal_id = notafiscal_id;
	}

	public String getNumerodanotafiscal() {
		return numerodanotafiscal;
	}

	public void setNumerodanotafiscal(String numerodanotafiscal) {
		this.numerodanotafiscal = numerodanotafiscal;
	}

	/* Métodos reescritos */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("\n--------------------" + this.getClass().getName() + "--------------------\n");
		builder.append("Número da nota fiscal: " + this.numerodanotafiscal);
		builder.append("\n--------------------" + this.getClass().getName() + "--------------------\n");
		return builder.toString();
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = super.hashCode();
		result = PRIME * result
				+ ((notafiscal_id == null) ? 0 : notafiscal_id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		final NotaFiscal other = (NotaFiscal) obj;
		if (notafiscal_id == null) {
			if (other.notafiscal_id != null)
				return false;
		} else if (!notafiscal_id.equals(other.notafiscal_id))
			return false;
		return true;
	}

}
